package com.tenton.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tenton.MyException.DataNotExist;
import com.tenton.MyException.InsufficientQuantity;
import com.tenton.mapper.*;
import com.tenton.pojo.DailySales;
import com.tenton.pojo.MonthlySales;
import com.tenton.pojo.Sales;
import com.tenton.pojo.Stock;
import com.tenton.service.SalesService;
import com.tenton.utils.Constants;
import com.tenton.utils.DateUtils;
import com.tenton.utils.IntegerUtils;
import com.tenton.vo.DailySalesReqVo;
import com.tenton.vo.MonthlySalesReqVo;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;

import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Date: 2021/1/9
 * @Author: Tenton
 * @Description:
 */
@Service
public class SalesServiceImpl implements SalesService {
    @Autowired
    SalesMapper salesMapper;
    @Autowired
    StockMapper stockMapper;
    @Autowired
    CommodityMapper commodityMapper;
    @Autowired
    DailySalesMapper dailySalesMapper;
    @Autowired
    MonthlySalesMapper monthlySalesMapper;

    /**
     * 删除销售记录
     *
     * @param id
     * @return
     */
    @Override
    public void deleteByPrimaryKey(Integer id, HttpSession session) {
        if (IntegerUtils.isEmpty(id)) {
            throw new NullPointerException("销售信息Id为空");
        } else {
            String name = (String) session.getAttribute("name");
            Date date = new Date();
            Sales sale = salesMapper.selectByPrimaryKey(id);
            Stock stock = stockMapper.StockWithCom(sale.getComId());
            //仓库中此商品的库存
            int stockNum = stock.getNum();
            //此次销售数量
            int saleNum = sale.getNum();
            //仓库中商品剩余库存
            stockNum = stockNum + saleNum;
            stock.setNum(stockNum);
            stock.setUpdateName(name);
            stock.setUpdateTime(date);
            stockMapper.updateByPrimaryKey(stock);
            DailySalesReqVo vo = new DailySalesReqVo();
            MonthlySalesReqVo monthReqVo = new MonthlySalesReqVo();
            //vo赋值
            BeanUtils.copyProperties(sale,vo);
            BeanUtils.copyProperties(sale,monthReqVo);
            salesMapper.deleteByPrimaryKey(id);
            //设置开始时间
            vo.setStartTime(DateUtils.setStartDate(vo.getSaleDate()));
            //设置结束时间
            vo.setEndTime(DateUtils.setEndDate(vo.getSaleDate()));
            DailySales dailySales = dailySalesMapper.selectByParam(vo);
            //日销售量
            int dailyNum = dailySales.getNum();
            dailyNum = dailyNum - saleNum;
            if (dailyNum > 0){
                dailySales.setNum(dailyNum);
                dailySalesMapper.updateByPrimaryKey(dailySales);
            }else {
                dailySalesMapper.deleteByPrimaryKey(dailySales.getId());
            }
            SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat monthSdf = new SimpleDateFormat("MM");
            String format = sdfDate.format(monthReqVo.getSaleDate());
            String month = monthSdf.format(monthReqVo.getSaleDate());
            try {
                monthReqVo.setStartTime(sdf.parse(format + "-01 00:00:00"));
                if (Constants.FEBRUARY.equals(month)){
                    monthReqVo.setEndTime(sdf.parse(format + "-28 23:59:59"));
                }else if (Constants.APRIL.equals(month) || Constants.JUNE.equals(month)|| Constants.SEPTEMBER.equals(month)|| Constants.NOVEMBER.equals(month)){
                    monthReqVo.setEndTime(sdf.parse(format + "-30 23:59:59"));
                }else {
                    monthReqVo.setEndTime(sdf.parse(format + "-31 23:59:59"));
                }
                MonthlySales monthlySales = monthlySalesMapper.selectByParam(monthReqVo);
                int monthlySalesNum = monthlySales.getNum();
                monthlySalesNum = monthlySalesNum - saleNum;
                if (monthlySalesNum > 0){
                    monthlySales.setNum(monthlySalesNum);
                    monthlySalesMapper.updateByPrimaryKey(monthlySales);
                }else {
                    monthlySalesMapper.deleteByPrimaryKey(monthlySales.getId());
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 新增销售记录
     *
     * @param sale
     * @param session
     * @return
     */
    @SneakyThrows
    @Override
    public void insert(Sales sale, HttpSession session) throws InsufficientQuantity, DataNotExist {
        if (sale == null) {
            throw new DataNotExist("销售信息为空");
        } else {
            String name = (String) session.getAttribute("name");
            Stock stock = stockMapper.StockWithCom(sale.getComId());
            //仓库中此商品的库存
            int stockNum = stock.getNum();
            //此次销售数量
            int saleNum = sale.getNum();
            //仓库中商品剩余库存
            if (stockNum >= saleNum) {
                Date date = new Date();
                sale.setCreateName(name);
                sale.setSaleDate(date);
                salesMapper.insert(sale);
                stockNum = stockNum - saleNum;
                stock.setNum(stockNum);
                stock.setUpdateName(name);
                stock.setUpdateTime(date);
                stockMapper.updateByPrimaryKey(stock);
                DailySalesReqVo vo = new DailySalesReqVo();
                //vo赋值
                BeanUtils.copyProperties(sale,vo);
                //设置开始时间
                vo.setStartTime(DateUtils.setStartDate(vo.getSaleDate()));
                //设置结束时间
                vo.setEndTime(DateUtils.setEndDate(vo.getSaleDate()));
                DailySales dailySales = dailySalesMapper.selectByParam(vo);
                //是否存在日销售量
                if (dailySales == null){
                    DailySales dailySale = new DailySales();
                    dailySale.setComId(sale.getComId());
                    dailySale.setComName(sale.getComName());
                    dailySale.setNum(saleNum);
                    dailySalesMapper.save(dailySale);
                }else {
                    //日销售量
                    int dailyNum = dailySales.getNum();
                    dailyNum = dailyNum + saleNum;
                    dailySales.setNum(dailyNum);
                    dailySalesMapper.updateByPrimaryKey(dailySales);
                }
                MonthlySalesReqVo monthlySalesReqVo = new MonthlySalesReqVo();
                BeanUtils.copyProperties(sale,monthlySalesReqVo);
                SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM");
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                SimpleDateFormat monthSdf = new SimpleDateFormat("MM");
                String format = sdfDate.format(monthlySalesReqVo.getSaleDate());
                String month = monthSdf.format(monthlySalesReqVo.getSaleDate());
                monthlySalesReqVo.setStartTime(sdf.parse(format + "-01 00:00:00"));
                if (Constants.FEBRUARY.equals(month)){
                    monthlySalesReqVo.setEndTime(sdf.parse(format + "-28 23:59:59"));
                }else if (Constants.APRIL.equals(month) || Constants.JUNE.equals(month)|| Constants.SEPTEMBER.equals(month)|| Constants.NOVEMBER.equals(month)){
                    monthlySalesReqVo.setEndTime(sdf.parse(format + "-30 23:59:59"));
                }else {
                    monthlySalesReqVo.setEndTime(sdf.parse(format + "-31 23:59:59"));
                }
                MonthlySales monthlySales = monthlySalesMapper.selectByParam(monthlySalesReqVo);
                if (monthlySales == null){
                    MonthlySales sales = new MonthlySales();
                    sales.setComId(sale.getComId());
                    sales.setComName(sale.getComName());
                    sales.setNum(sale.getNum());
                    monthlySalesMapper.save(sales);
                }else {
                    int num = monthlySales.getNum();
                    num = num + saleNum;
                    monthlySales.setNum(num);
                    monthlySalesMapper.updateByPrimaryKey(monthlySales);
                }
            } else {
                throw new InsufficientQuantity("商品库存不足");
            }
        }
    }

    /**
     * 获取所有销售记录
     *
     * @param pn
     * @param model
     * @return
     */
    @Override
    public void getAll(Integer pn, ModelMap model) {
        PageHelper.startPage(pn, Constants.PAGE_SIZE);
        List<Sales> sales = salesMapper.selectAll();
        PageInfo<Sales> pageInfo = new PageInfo<Sales>(sales);
        model.addAttribute("pageInfo", pageInfo);
    }

    /**
     * 查询销售记录
     *
     * @param id
     * @param model
     */
    @Override
    public void selectByPrimaryKey(Integer id, Model model) {
        if (IntegerUtils.isEmpty(id)) {
            throw new NullPointerException("销售信息Id为空");
        } else {
            Sales sales = salesMapper.selectByPrimaryKey(id);
            model.addAttribute("sale", sales);
        }
    }

    /**
     * 查询销售记录
     *
     * @param id
     * @return
     */
    @Override
    public Sales selectById(Integer id) {
        if (IntegerUtils.isEmpty(id)) {
            throw new NullPointerException("销售信息Id为空");
        } else {
            return salesMapper.selectByPrimaryKey(id);
        }
    }
    /**
     * 商品名称模糊查询
     *
     * @param comName
     * @param pn
     * @param model
     * @return
     */
    @Override
    public void getByParams(String comName, Integer pn, ModelMap model) {
        PageHelper.startPage(pn, Constants.PAGE_SIZE);
        List<Sales> sale = salesMapper.getByParams(comName);
        PageInfo<Sales> pageInfo = new PageInfo<Sales>(sale);
        model.addAttribute("pageInfo", pageInfo);
    }

    /**
     * 商品中销售统计
     * @return
     */
    @Override
    public List<Map<String, Object>> pieData() {
        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> listData = salesMapper.count();
        if (listData.size() > 0) {
            for (int i = 0; i < listData.size(); i++) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("name", listData.get(i).get("comName"));
                map.put("value", listData.get(i).get("num"));
                data.add(map);
            }
        }
        return data;
    }


    /**
     * 获取销量当前日前七天销量
     *
     * @param comName
     */
    public List<Integer> sevenDaySales(String comName){
        //存储销量
        List<Integer> list = new ArrayList<>();
        //当天销售详细
        Date oneDate = new Date();
        int one = this.toDaySale(comName, oneDate);
        //一天前销售详细
        Date twoDate = DateUtils.getYesterday(oneDate);
        int two = this.toDaySale(comName, twoDate);
        //两天前销售详细
        Date threeDate = DateUtils.getYesterday(twoDate);
        int three = this.toDaySale(comName, threeDate);
        //三天前销售详细
        Date fourDate = DateUtils.getYesterday(threeDate);
        int four = this.toDaySale(comName, fourDate);
        //四天前销售详细
        Date fiveDate = DateUtils.getYesterday(fourDate);
        int five = this.toDaySale(comName, fiveDate);
        //五天前销售详细
        Date sixDate = DateUtils.getYesterday(fiveDate);
        int six = this.toDaySale(comName, sixDate);
        //六天前销售详细
        Date sevenDate = DateUtils.getYesterday(sixDate);
        int seven = this.toDaySale(comName, sixDate);
        list.add(seven);
        list.add(six);
        list.add(five);
        list.add(four);
        list.add(three);
        list.add(two);
        list.add(one);
        return list;
    }

    /**
     * 近七天时间
     * @return
     */
    public List<String> sevenTime(){
        List<String> list = new ArrayList<>();
        Date one = new Date();
        Date two = DateUtils.getYesterday(one);
        Date three = DateUtils.getYesterday(two);
        Date four = DateUtils.getYesterday(three);
        Date five = DateUtils.getYesterday(four);
        Date six = DateUtils.getYesterday(five);
        Date seven = DateUtils.getYesterday(six);
        list.add(DateUtils.getYmdDate(seven));
        list.add(DateUtils.getYmdDate(six));
        list.add(DateUtils.getYmdDate(five));
        list.add(DateUtils.getYmdDate(four));
        list.add(DateUtils.getYmdDate(three));
        list.add(DateUtils.getYmdDate(two));
        list.add(DateUtils.getYmdDate(one));
        return list;
    }
    /**
     * 获取前一天商品日销量
     * @param comName
     * @param date
     */
    public int toDaySale(String comName, Date date){
        DailySalesReqVo vo = new DailySalesReqVo();
        //vo赋值
        vo.setComName(comName);
        vo.setSaleDate(date);
        //设置开始时间
        vo.setStartTime(DateUtils.setStartDate(date));
        //设置结束时间
        vo.setEndTime(DateUtils.setEndDate(date));
        DailySales dailySales = dailySalesMapper.selectByParam(vo);
        if (dailySales == null){
            return Constants.DAILY_SALE_NUM;
        }else {
            return dailySales.getNum();
        }
    }

    /**
     * 获取近半年销量
     *
     * @param comName
     */
    public List<Integer> halfYearSales(String comName){
        //存储销量
        List<Integer> list = new ArrayList<>();
        Calendar c = Calendar.getInstance();
        int one = this.currentMonthSale(c, comName, Constants.CURRENT_MONTH);
        int two = this.currentMonthSale(c, comName, Constants.LAST_MONTH);
        int three = this.currentMonthSale(c, comName, Constants.LAST_MONTH);
        int four = this.currentMonthSale(c, comName, Constants.LAST_MONTH);
        int five = this.currentMonthSale(c, comName, Constants.LAST_MONTH);
        int six = this.currentMonthSale(c, comName, Constants.LAST_MONTH);
        list.add(six);
        list.add(five);
        list.add(four);
        list.add(three);
        list.add(two);
        list.add(one);
        return list;
    }

    /**
     * 近半年月份
     * @return
     */
    public List<String> currentMonthDate(){
        List<String> list = new ArrayList<>();
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        //本月
        c.add(Calendar.MONTH, Constants.CURRENT_MONTH);
        String one = sdf.format(c.getTime());
        //上一月
        c.add(Calendar.MONTH, Constants.LAST_MONTH);
        String two = sdf.format(c.getTime());
        //上第二月
        c.add(Calendar.MONTH, Constants.LAST_MONTH);
        String three = sdf.format(c.getTime());
        //上第三月
        c.add(Calendar.MONTH, Constants.LAST_MONTH);
        String four = sdf.format(c.getTime());
        //上第四月
        c.add(Calendar.MONTH, Constants.LAST_MONTH);
        String five = sdf.format(c.getTime());
        //上第五月
        c.add(Calendar.MONTH, Constants.LAST_MONTH);
        String six = sdf.format(c.getTime());
        list.add(six);
        list.add(five);
        list.add(four);
        list.add(three);
        list.add(two);
        list.add(one);
        return list;
    }
    /**
     * 获取当前月销量
     * @param c
     * @param comName
     * @param month
     * @return
     */
    public int currentMonthSale(Calendar c,String comName,int month){
        MonthlySalesReqVo vo = new MonthlySalesReqVo();
        //vo赋值
        vo.setComName(comName);
        try {
            //每月最初一天
            c.add(Calendar.MONTH, month);
            c.set(Calendar.DAY_OF_MONTH, Constants.DAY_OF_MONTH_START);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String startTime = sdf.format(c.getTime());
            vo.setStartTime(DateUtils.setStartDate(sdf.parse(startTime)));
            //每月最后一天
            c.add(Calendar.MONTH, Constants.MONTH);
            c.set(Calendar.DAY_OF_MONTH, Constants.DAY_OF_MONTH_END);
            String entTime = sdf.format(c.getTime());
            vo.setSaleDate(sdf.parse(entTime));
            vo.setEndTime(DateUtils.setEndDate(sdf.parse(entTime)));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        MonthlySales monthlySales = monthlySalesMapper.selectByParam(vo);
        if (monthlySales == null){
            return Constants.MONTH_SALE_NUM;
        }else {
            return monthlySales.getNum();
        }
    }
}
